---
id: getting-started
title: Getting Started
sidebar_label: Getting Started
slug: /guides
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

## Installing the library

1. Install [react-native-filament](https://www.npmjs.com/package/react-native-filament):

```sh
npm i react-native-filament
```

2. `react-native-filament` depends on [`react-native-worklets-core`](https://github.com/margelo/react-native-worklets-core):

```sh
npm i react-native-worklets-core
```

For react-native-worklets-core its necessary to add a plugin to your `babel.config.js` as well:

<Tabs
  groupId="rnwcInstallationPlugin"
  defaultValue="wo_rea"
  values={[
    {label: 'Without reanimated', value: 'wo_rea'},
    {label: 'When using reanimated', value: 'w_rea'}
  ]}>
  <TabItem value="wo_rea">
    ```js
    module.exports = {
      plugins: [
        ["react-native-worklets-core/plugin", { processNestedWorklets: true }],
        // ...
      ],
      // ...
    };
    ```

  </TabItem>

  <TabItem value="w_rea">
    You should already use the reanimated babel pluginVersions, make sure to add the `processNestedWorklets` option to it:

    ```js
    module.exports = {
      plugins: [
        ["react-native-reanimated/plugin", { processNestedWorklets: true }],
        // ...
      ],
      // ...
    };
    ```

  </TabItem>
</Tabs>

3. Update your pods:

```sh
cd ios && pod install
```

4. Start Metro with clean cache:

```sh
npm start -- --reset-cache
```

:::tip Good to know
The npm package of react-native-filament is quite huge, around ~400mb. That's because we need to ship all static libraries for all architectures for both android and iOS. **The actual size of the library in your downloadable app is around ~4mb**.
:::

## Configure metro

You'll likely import 3D related files when using react-native-filament. To make sure metro can resolve these files, you need to add the following to your `metro.config.js`:

```js
const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");

const defaultConfig = getDefaultConfig(__dirname);

/**
 * Metro configuration
 * https://metrobundler.dev/docs/configuration
 *
 * @type {import('metro-config').MetroConfig}
 */
const config = {
  resolver: {
    // This makes it possible to import .glb files in your code:
    assetExts: [...(defaultConfig.resolver?.assetExts || []), "glb"],
  },
};

module.exports = mergeConfig(defaultConfig, config);
```

:::info
Currently only loading `.glb` files is supported. You can convert any other 3D models (gltf, obj, FBX, etc) to .glb using blender or online converter tools.
:::

## Basic example: Render your first 3D model

For seeing some 3D content on the screen in your app, you need the following things:

- 🏞️ A view to draw the 3D content to (the `<FilamentView>` component)
- 💡 A light source, otherwise the scene will be black (the `<DefaultLight>` component)
- 📦 A 3D model file (e.g. a .glb file)
- 📹 A camera through which the scene is observed and projected onto the view (the `<Camera>` component)

```jsx
import {
  FilamentScene,
  FilamentView,
  DefaultLight,
  Model,
  Camera,
} from "react-native-filament";
import MyModel from "./MyModel.glb";

function MyScene() {
  return (
    <FilamentScene>
      {/* 🏞️ A view to draw the 3D content to */}
      <FilamentView style={{ flex: 1 }}>
        {/* 💡 A light source, otherwise the scene will be black */}
        <DefaultLight />

        {/* 📦 A 3D model */}
        <Model source={MyModel} />

        {/* 📹 A camera through which the scene is observed and projected onto the view */}
        <Camera />
      </FilamentView>
    </FilamentScene>
  );
}
```

Additionally you see that we use the `<FilamentScene>` component to wrap our scene. This is necessary to provide the necessary react context for the scene to work correctly.

Everything that's part of your 3D scene should be rendered as part of the `<FilamentView>` component.

:::warning
Trying to render regular react-native components inside the `<FilamentView>` might work, but is not directly supported and might lead to unexpected behavior. Instead you can
render on top of it by using a `position: absolute` view.
:::

In general react-native-filament leans towards a declartive API that works well with React.
